const _transform_tool = require("../utils/transform_tool");
const { progress } = require("../utils/display_tool");
const { getLastError, resetError, log } = require("../utils/log_tool");
const { BaseCommand, PROCESS_STATE } = require("./base");

class LoopCommand extends BaseCommand {
    async execute() {
        const data = this.selfData;
        let content = this.content;
        if (data.delimiter) {
            content = content.split(new RegExp(data.delimiter));
        }
        const keys = Object.keys(content);
        const show_progress = this.selfCfg.show_progress;
        for (let loop_index = 0; loop_index < keys.length; loop_index++) {
            if (this.globalData.process_state === PROCESS_STATE.BREAK) {
                this.resetProcessState();
                break;
            } else if (
                this.globalData.process_state === PROCESS_STATE.CONTINUE
            ) {
                this.resetProcessState();
            }
            const loop_key = keys[loop_index];
            const loop_data = content[loop_key];
            // 键索引值映射
            if (data.index_mapping) {
                this.shareData[data.index_mapping] = loop_index;
            } else {
                this.shareData.loop_index = loop_index;
            }
            // 键映射
            if (data.key_mapping) {
                this.shareData[data.key_mapping] = loop_key;
            } else {
                this.shareData.loop_key = loop_key;
            }
            // 值映射
            const value_mapping = data.value_mapping;
            if (value_mapping) {
                if (typeof value_mapping === "string") {
                    this.shareData[value_mapping] = loop_data;
                } else if (Array.isArray(value_mapping)) {
                    for (let i = 0; i < value_mapping.length; i++) {
                        const k = value_mapping[i];
                        this.shareData[k] = loop_data[i];
                    }
                } else if (typeof value_mapping === "object") {
                    for (const key in value_mapping) {
                        if (Object.hasOwn(value_mapping, key)) {
                            const element = value_mapping[key];
                            this.shareData[element] = loop_data[key];
                        }
                    }
                } else if (typeof value_mapping === "boolean") {
                    for (const key in loop_data) {
                        if (Object.hasOwn(loop_data, key)) {
                            this.shareData[key] = loop_data[key];
                        }
                    }
                }
            } else {
                this.shareData.loop_data = loop_data;
            }
            let tip = "";
            if (data.tip_key !== undefined) {
                if (typeof data.tip_key === "boolean") {
                    tip = `[${loop_data}]`;
                } else {
                    const tipKeys = _transform_tool.toArray(data.tip_key);
                    tip = `[${tipKeys.map(key => this.getDataByKey(key)).join("/")}]`;
                }
            }
            if (show_progress) {
                ++this.shareData.$COMPRESS_PROGERSS;
                // log("");
                progress(loop_index, keys.length, {
                    desc: `> ${this.selfCfg.title || this.selfCfg.type}${tip}`,
                    color: "cyan",
                });
                // log("");
            }
            let commandCfgs = data.commands;
            // 特殊处理字符的情况
            if (typeof commandCfgs === "string") {
                commandCfgs = this.formatData(commandCfgs);
            }
            // 默认从循环开始执行，增加深度
            await this.exec(commandCfgs, this.depth + 1);
            if (show_progress) {
                --this.shareData.$COMPRESS_PROGERSS;
                if (!getLastError()) {
                    progress(loop_index + 1, keys.length, {
                        desc: `> ${this.selfCfg.title || this.selfCfg.type}${tip}`,
                        color: "cyan",
                    });
                } else {
                    progress(loop_index + 1, keys.length, {
                        desc: `> ${this.selfCfg.title || this.selfCfg.type}${tip}`,
                        color: "cyan",
                    });
                }
                // log("");
            }
            if (getLastError()) {
                if (this.selfCfg.ignore_error) {
                    resetError(this.selfCfg.ignore_error);
                } else {
                    throw getLastError();
                }
            }
        }
        if (show_progress) {
            log("");
        }
        // 最后一个循环结束后，需要重置掉执行状态
        this.resetProcessState();
    }

    getRequireContent() {
        return true;
    }
}

module.exports = {
    LoopCommand,
};
